package com.yihong.zuulserver.filter;

import com.alibaba.fastjson.JSON;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.yihong.common.util.AjaxJson;
import com.yihong.common.util.AjaxJsonFactory;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName SecurityFilter
 * @Description 登录拦截
 *              拦截器，如果return null 正常访问各个微服务的接口
 *              如果被拦截器拦截将会返回处理的信息，也将不会访问日志记录
 * @Author 孟志浩
 * @Date 2019/3/19 15:31
 **/
@Component
public class SecurityFilter extends ZuulFilter {

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${login.keepTime}")
    private Long keepTime;

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException{
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        HttpServletResponse response = ctx.getResponse();
        String url = request.getRequestURL().toString();
        if (!url.contains("/login")) {
            AjaxJson resJson = AjaxJsonFactory.createAjaxJson(405, "请登录后访问");
            // 获取请求的tokenKey
            String tokenKey = request.getHeader("Authorization");
            // 没有携带tokenKey
            if (StringUtils.isBlank(tokenKey)) {
                // 验证不通过
                ctx.setSendZuulResponse(false);
                ctx.setResponseBody(JSON.toJSONString(resJson));
                return false;
            }
            // 判断tokenKey是否在Redis中过期
            if (!redisTemplate.hasKey(tokenKey)) {
                ctx.setSendZuulResponse(false);
                ctx.setResponseBody(JSON.toJSONString(resJson));
                return false;
            } else {
                redisTemplate.opsForValue().set(tokenKey, "p", keepTime, TimeUnit.SECONDS);
            }
        }
        return null;
    }
}
